﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace ScarEngine
{

    public class MasterManager
    {
        public static GraphicsManager GraphicsManager;
        public static PhysicsManager PhysicsManager;
        public static List<GameObject> GameObjects;
        protected List<GameObject> DeleteList;
        public PositionalObject Test;
        public Texture2D DefaultTex = null;
        public SpriteFont DefaultFont;

        public MasterManager()
        {
            DeleteList = new List<GameObject>();
            GameObjects = new List<GameObject>();
            GraphicsManager = new GraphicsManager();
            PhysicsManager = new PhysicsManager();
        }

        public void Init() // Called at the very start
        {

            

            #region Core

            LevelManager.Init();

            DefaultTex = Game1.Game.Content.Load<Texture2D>("Textures\\OnePixelWhite");
            DefaultFont = Game1.Game.Content.Load<SpriteFont>("Fonts\\Arial");

            LevelManager.AddLevel<DefaultLevel>("Default"); // DEFAULT LEVEL DO NOT REMOVE
            

            #endregion
        }

        public void BeginRun() // Called right before the first update runs
        {
            GraphicsManager.PreRun();
            LevelManager.ChangeLevel("Default");
        }

        public void Update(GameTime gameTime) // Called on Update
        {
            #region Update Level
            LevelManager.UpdateLevel(gameTime);
            #endregion
            #region Update Physics
            PhysicsManager.Update(gameTime);
            #endregion
            #region Update GameObjects
            foreach (GameObject gameObject in GameObjects)
            {
                gameObject.Update(gameTime);
                if (gameObject.ToDelete())
                {
                    DeleteList.Add(gameObject);
                }
            }
            #endregion
            #region Delete Un-needed GameObjects
            foreach (GameObject gameObject in DeleteList)
            {
                foreach (KeyValuePair<string, Component> pair in gameObject.Components)
                {
                    pair.Value.Delete();
                }
                gameObject.Components = null;
                Game1.MasterManager.UnRegisterGameObject(gameObject);
            }
            DeleteList.Clear();
            #endregion

        }

        public void Draw(GameTime gameTime) // Called on Draw
        {
            GraphicsManager.Draw(gameTime);
        }



        public void UnRegisterGameObject(GameObject gameObject)
        {
            GameObjects.Remove(gameObject);
        }




    }

    public class ComponentCreator
    {
        public static Component CreateComponent<ComponentType>() where ComponentType : Component, new()
        {
            return new ComponentType() as ComponentType;
        }
    }

}